package com.soft.bams.client;

import com.soft.bams.entity.Account;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.net.Socket;

/**
 * @author yzh
 * @desc TODO
 * @date 2025/5/5
 */
public class ATMClient extends JFrame {
    MainPanel mainPanel;
    RegisterPanel registerPanel;
    LoginPanel loginPanel;
    BusinessPanel businessPanel;

    Account account;

    private Socket socket;
    private ObjectInputStream ois;
    private PrintWriter pw;
    private static final String SERVER_HOST = "localhost";
    private static final int SERVER_PORT = 8888;

    private boolean isRunning = true;
    private Thread balanceChecker;
    private volatile boolean forceRefresh = false;

    public ATMClient() {
        this.setTitle("ATM 客户端");
        this.setSize(400, 400);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        this.setResizable(false);

        try {
            socket = new Socket(SERVER_HOST, SERVER_PORT);
            pw = new PrintWriter(socket.getOutputStream(),true);
            ois = new ObjectInputStream(socket.getInputStream());

        } catch (IOException e) {
            JOptionPane.showMessageDialog(this, "无法连接到服务器: " + e.getMessage(),"错误",JOptionPane.ERROR_MESSAGE);
            System.exit(0);
        }

        mainPanel = new MainPanel();
        registerPanel = new RegisterPanel(this);
        loginPanel = new LoginPanel(this);
        businessPanel = new BusinessPanel(this);

        Container container = this.getContentPane();
        container.setLayout(new CardLayout());
        container.add(mainPanel, "main");
        container.add(registerPanel, "register");
        container.add(loginPanel, "login");
        container.add(businessPanel, "business");

        // 启动余额检查线程
        startBalanceChecker();

        // 窗口关闭事件
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent windowEvent) {
                isRunning = false;
                if (balanceChecker != null) {
                    balanceChecker.interrupt();
                }
                removeAccountFromMap();
                try {
                    if (socket != null) socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

    }

    //余额检查
    private void startBalanceChecker() {
        balanceChecker = new Thread(() -> {
            long lastCheckTime = 0;
            while (isRunning && !socket.isClosed()) {
                try {
                    long currentTime = System.currentTimeMillis();
                    // 每200毫秒检查一次或强制刷新时检查
                    if (forceRefresh || currentTime - lastCheckTime >= 200) {
                        if (account != null) {
                            Object response = sendCommand("getBalance#" + account.getId());
                            if (response instanceof Account) {
                                Account updatedAccount = (Account) response;
                                if (forceRefresh || updatedAccount.getBalance() != account.getBalance()) {
                                    account = updatedAccount;
                                    SwingUtilities.invokeLater(() -> {
                                        if (businessPanel.isVisible()) {
                                            businessPanel.initBusiness();
                                        }
                                    });
                                    forceRefresh = false;
                                }
                            }
                        }
                        lastCheckTime = currentTime;
                    }
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        balanceChecker.start();
    }

    public void forceBalanceRefresh() {
        this.forceRefresh = true;
    }

    public synchronized Object sendCommand(String command) {
        try {
            pw.println(command);
            return ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            JOptionPane.showMessageDialog(this, "通信错误: " + e.getMessage(),"错误",JOptionPane.ERROR_MESSAGE);
            return null;
        }
    }

    public void removeAccountFromMap() {
        if (account != null) {
            Object response = sendCommand("removeAccountFromMap#" + account.getId());
            account = null;
            JOptionPane.showMessageDialog(this,response);
        }
    }

    public static void main(String[] args) {
        new ATMClient().setVisible(true);

    }
}
